Modern high performance microprocessors have an ever-increasing number of circuit elements and an ever-rising clock frequency. Also, as the number of circuits that can be used in a CPU has increased, the number of parallel operations performed by the circuits has risen. Examples of efforts to create more parallel operations include increased pipeline depth and an increase in the number of functional units in super-scalar and very-long-instruction-word architectures. As CPU performance continues to increase, the result has been a larger number of circuits switching at faster rates. Thus, from a circuit design perspective, important considerations such as the time needed to complete a circuit simulation and the time needed to debug the CPU are taken into account.
As each new CPU design uses more circuits and circuit elements, each often operating at increased frequencies, the time required to simulate the circuit design increases. Due to the increased time for simulation, the number of tests, and consequently the test coverage, may decrease. In general, the result has been a dramatic increase in the number of logic errors that escape detection before the CPU is manufactured.
Circuit simulation may occur at a “switch-level.” Switch-level simulations typically include active circuit elements (e.g., transistors) and passive circuit elements (e.g., resistors, capacitors, and inductors). Circuit simulation also may occur at a “behavioral level.” Behavioral level simulations typically use a hardware description language (HDL) that determines the functionality of a single circuit element or group of circuit elements.
A typical behavioral level simulation language is “Verilog,” which is an Institute of Electrical and Electronics Engineers standard. Verilog HDL uses a high-level programming language to describe the relationship between the input and output of one or more circuit elements. Verilog HDL describes on what conditions the outputs should be modified and what effect the inputs have. Verilog HDL programs may also be used for logic simulation at the “register transfer level” (RTL). RTL is a programming language used to describe a circuit design. The RTL programs written in Verilog go through a verification process. During this process, the Verilog design is parsed and checked for RTL style conformance by a style checker.
Using the Verilog HDL, for example, digital systems are described as a set of modules. Each module has a port interface, which defines the inputs and outputs for the module. The interface describes how the given module connects to other modules. Modules can represent elements of hardware ranging from simple gates to complete systems. Each module can be described as an interconnection of sub-modules, as a list of terminal elements, or a mixture of both. Terminal elements within a module can be described behaviorally, using traditional procedural programming language constructs such as “if” statements and assignments, and/or structurally as Verilog primitives. Verilog primitives include, for example, truth tables, Boolean gates, logic equation, pass transistors (switches), etc.
HDL simulations, written using HDL languages, may be event-driven or cycle-based. Event-driven simulators are designed to eliminate unnecessary gate simulations without introducing an unacceptable amount of additional testing. Event-driven simulators propagate a change in state from one set of circuit elements to another. Event-driven simulators may record relative timing information of the change in state so that timing and functional correctness may be verified. Event-driven simulators use event queues to order and schedule the events. Event-driven simulators process and settle all the active events in a time step before the simulator can move to the next time step.
Cycle-based simulators also simulate a change in state from one set of circuit elements to another; however, the state of an entire system is evaluated once each clock cycle. Cycle-based simulators are applicable to synchronous digital systems and may be used to verify the functional correctness of a digital design. Cycle-based simulators abstract away the timing details for all transactions that do not occur on a cycle boundary. Cycle-based simulators use algorithms that eliminate unnecessary calculations to achieve improved performance in verifying system functionality. Discrete component evaluations and re-evaluations are typically unnecessary upon the occurrence of every event.
Cycle-based simulators typically have enhanced performance. Depending on the particular options used, cycle-based simulators can offer five to ten times improvement in speed and one-fifth to one-third the memory utilization over conventional, event-driven simulators. Some cycle-based simulators also offer very fast compile times. For very large designs, the reduced memory requirements of cycle-based simulators allow a design team to simulate a design on almost every workstation on their network.
A typical simulation system (e.g., cycle-based simulator) is shown in FIG. 1. A simulation design source code (100), which includes, for example, Verilog files, clock files, etc., is an input into a simulation design compiler (102). The simulation design compiler (102) statically generates simulation design object code (104). A linker/loader (106) takes as input the simulation design object code (104) and a test vector object code (108), which is output from a stimulus compiler (110). Test vector source code (112) is input into the stimulus compiler (110).
The test vector object code (108) provides stimulus in the form of input signal values for the simulation, which is run on the simulator (114). For example, if a particular module included in the simulation design object code (104) includes an AND gate, the test vector object code (108) may provide stimulus in the form of a signal value equal to “1” to be sent to a pin of the AND gate at a particular time. The test vector object code (108) may also include expected outputs for signal values stimuli.
The test vector object code (108) may include multiple test vectors. For example, a collective test vector may include a first test vector to test a first group of modules of the simulation design object code (104), and a second test vector to test a second group of modules of the simulation design object code (104).
Using the test vector (108) and the simulation design object code (104), the linker/loader (106) generates and loads an executable code (i.e., an executable program or simulation image) into the memory of simulator (114), where the simulation is performed. Depending on implementation, the simulator may use typical, “standard” computer architectures, such as may be found in a workstation, or may use other, “non-standard” computer architectures, such as computer architectures developed specifically for simulation or specifically for verification of circuit design, e.g., a massively parallel processing machine.